package com.deying.httplockserver.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
 * 处理者管理器
 * @author jjliu
 *
 */
@Component
public class WorkerManager {
	private final Logger logger = LoggerFactory.getLogger(WorkerManager.class);
	@Resource
	SimpMessagingTemplate simpMessagingTemplate;
	/**统计线程*/
	ScheduledExecutorService  scheduledExecutorService  = Executors.newScheduledThreadPool(1);
	/**cpu核数*/
	int coreNum;
	/**处理者哈希分组*/
	Map<Integer, Worker> workerMap = new TreeMap<Integer, Worker>();
	
	@Value("${console.interval}")
	int consoleInterVal;
	
	public WorkerManager() {
		coreNum = Runtime.getRuntime().availableProcessors();
		logger.info("锁服务工作线程数量{}",coreNum);
		for(int i=0;i<coreNum;i++){
			workerMap.put(i, new Worker());
		}
	}
	
	@PostConstruct
	public void init(){
		scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
			@Override
			public void run() {
				ArrayNode tableData =  JsonNodeFactory.instance.arrayNode();
				for(Worker worker : workerMap.values()){
					HashMap<String, ArrayList<HttpLockRequest>> readMap = new HashMap<String, ArrayList<HttpLockRequest>>(worker.getRequestMap());
					for(Entry<String, ArrayList<HttpLockRequest>> entry :  readMap.entrySet()){
						String name = entry.getKey();
						ArrayList<HttpLockRequest> requestList = entry.getValue();
						if(requestList==null || requestList.size()==0){
							logger.error("{} empty  error!!!",name);
						}else{
							HttpLockRequest request = requestList.get(0);
							long lockedTimestamp = request.getLockedTimestamp();
							long lockedTime = (System.currentTimeMillis() - lockedTimestamp);
//							System.out.println(name+" 数量:"+requestList.size()+" 已锁定秒:"+lockedTime+"["+request.getLockTime()/1000+"]");
							ObjectNode tableItem = JsonNodeFactory.instance.objectNode();
							tableItem.put("name", request.getName());
							tableItem.put("tid", request.getTid());
							tableItem.put("reenterNum", request.getReenterNum());
							tableItem.put("waitnum",requestList.size()-1);
							tableItem.put("locktime", lockedTime);
							tableItem.put("maxlocktime", request.getLockTime());
							tableData.add(tableItem);
						}
					}
				}
				simpMessagingTemplate.convertAndSend("/topic/status",tableData);
			}
		}, 5, consoleInterVal, TimeUnit.SECONDS);
	}
	
	public void lock(HttpLockRequest request){
		int coreIndex = Math.abs(request.getName().hashCode())%coreNum;
//		System.out.println("coreIndex:"+coreIndex);
		Worker worker = workerMap.get(coreIndex);
		worker.postLock(request);
	}
	
	public void unLock(HttpLockRelease httpLockRelease){
		int coreIndex = Math.abs(httpLockRelease.getName().hashCode())%coreNum;
		Worker worker = workerMap.get(coreIndex);
		worker.postUnLock(httpLockRelease);
	}

}
